/**
 * 
 */
package com.lvan.service.system;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.lvan.bean.Page;
import com.lvan.bean.User;
import com.lvan.bean.BaseException;
import com.lvan.constant.ValidateRecord;
import com.lvan.dao.mapper.UserMapper;
import com.lvan.service.AbstractService;
import com.lvan.service.Bb;
import com.lvan.service.interfaze.IService;
import com.lvan.service.interfaze.system.IUserService;
import com.lvan.util.InputValidate;
import com.lvan.util.MD5Util;
import com.lvan.util.StringUtil;

/**
 * @author lvan.he<br>
 *         2013-6-26<br>
 * @version 1.0.0.0
 */
@Service("userService")
@Transactional
public class UserService extends AbstractService implements IUserService {
	Logger loger = LoggerFactory.getLogger(this.getClass());
	@Autowired
	private UserMapper userMapper;
	private InputValidate<User> validator = new InputValidate<User>();

	@Override
	public User login(User user, String ip) throws BaseException {
		if (user == null)
			throw new BaseException(LOGIN_FAIL, USER_UNDEFINED, "请求错误");
		if (StringUtil.isBlank(user.getUserName()))
			throw new BaseException(LOGIN_FAIL, USERNAME_REQUIRED, "用户名不能为空");
		if (user.getUserPwd() == null)
			throw new BaseException(LOGIN_FAIL, REQUEST_PARAM_ERROR, "请求参数有误");
		User curUser = userMapper.queryByName(user.getUserName());
		if (curUser == null)
			throw new BaseException(LOGIN_FAIL, NO_USER, "用户名不存在");
		if (curUser.getUserStatus() == USER_LOCKED)
			throw new BaseException(LOGIN_FAIL, USER_LOCKED, "该用户被锁定");
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MINUTE,
				-Integer.parseInt(Bb.getProperty(LOCK_DATE, USER_CONFIG)));
		if (curUser.getUserStatus() == USER_LOCKED_BY_MULTI_ERROR_LOGIN
				&& curUser.getLastLoginDate().after(calendar.getTime())) {
			throw new BaseException(LOGIN_FAIL,
					USER_LOCKED_BY_MULTI_ERROR_LOGIN, "登录过于频繁，已被锁定!",(curUser.getLastLoginDate().getTime()-calendar.getTime().getTime())+"");
		}
		if ((!StringUtil.isBlank(curUser.getUserPwd()) && StringUtil
				.isBlank(user.getUserPwd()))
				|| (!MD5Util.MD5Encode(user.getUserPwd()).equals(
						curUser.getUserPwd()))) {
			curUser.setFailLoginTimes(curUser.getFailLoginTimes() + 1);
			if (curUser.getFailLoginTimes() % 5 == 0) {
				curUser.setLastLoginDate(new Date());
				curUser.setUserStatus(3);
			}
			userMapper.update(curUser);
			throw new BaseException(LOGIN_FAIL, PWD_ERROR, "密码错误");
		}
		curUser.setLastLoginIp(ip);
		curUser.setLastLoginDate(new Date());
		curUser.setFailLoginTimes(0);
		curUser.setUserStatus(0);
		userMapper.update(curUser);
		return curUser;
	}

	@Override
	public void update(User user) throws BaseException {
		if (user.getUserId() == -1) {
			throw new BaseException("", IService.PK_ID_REQUIRED, "ID为必须数据");
		}
		if (StringUtil.isBlank(user.getUserPwd())) {
			user.setUserPwd(null);
		}else {
			user.setUserPwd(MD5Util.MD5Encode(user.getUserPwd()));
		}
		Set<ValidateRecord> constraintViolations = validator.validate(user,
				false);
		if (!constraintViolations.isEmpty()) {
			StringBuilder sb = new StringBuilder();
			for (ValidateRecord record : constraintViolations) {
				sb.append(record.getMessage() + "; ");
			}
			throw new BaseException("", REQUEST_PARAM_ERROR, sb.toString());
		}
		userMapper.update(user);
	}

	@Override
	public List<User> query(User user, Page page) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("user", user);
		params.put("page", page.getPageSql());
		params.put("orderBy", user.convertField2Column());
		page.setTotal(this.count(user));
		return userMapper.query(params);
	}

	@Override
	public User getByID(Serializable userId) {
		return userMapper.queryById(userId);
	}

	@Override
	public void add(User user) throws BaseException {
		Set<ValidateRecord> constraintViolations = validator.validate(user,
				true);
		if (!constraintViolations.isEmpty()) {
			StringBuilder sb = new StringBuilder();
			for (ValidateRecord record : constraintViolations) {
				sb.append(record.getMessage() + "; ");
			}
			throw new BaseException("", REQUEST_PARAM_ERROR, sb.toString());
		}
		user.setUserPwd(MD5Util.MD5Encode(user.getUserPwd()));
		user.setFailLoginTimes(0);
		user.setLastLoginDate(new Date());
		user.setUserStatus(0);
		try {
			userMapper.addUser(user);
		} catch (DuplicateKeyException e) {
			throw new BaseException("", UNIQUE_ERROR, "此用户名已存在");
		}
	}

	@Override
	public boolean hasUseByName(User user) throws BaseException {
		return userMapper.queryByName(user.getUserName()) != null;
	}

	@Override
	public void delete(Serializable ids) throws BaseException {
		userMapper.delete(ids);
	}

	@Override
	public int count(User o) {
		return userMapper.count(o);
	}

	@Override
	public void logout(User user) throws BaseException {

	}

}
